<template>
<div class="tab-pane active" id="nvr-config" v-loading.fullscreen.lock="bRedirecting" element-loading-text="修改了页面访问端口，即将跳转...">
    <form role="form" class="form-horizontal" autocomplete="off" @submit.prevent="onSubmit" data-vv-scope="base">
        <div :class="['form-group' , {'has-error': errors.has('base.ServiceWanPort')}]">
            <label for="base-service-lan-port" class="col-sm-3 control-label">HTTP 端口</label>
            <div class="col-sm-8">
                <input id="base-service-lan-port" type="text" class="form-control" name="ServiceWanPort" data-vv-as="HTTP 端口" v-validate="'required|numeric'" v-model.trim.number="ServiceWanPort">
                <span class="help-block">{{errors.first('base.ServiceWanPort')}}</span>
            </div>
        </div>
        <div :class="['form-group' , {'has-error': errors.has('base.RTMPPort')}]">
            <label for="base-rtmp-port" class="col-sm-3 control-label">RTMP 端口</label>
            <div class="col-sm-8">
                <input id="base-rtmp-port" type="text" class="form-control" name="RTMPPort" data-vv-as="RTMP 端口" v-validate="'required|numeric'" v-model.trim.number="RTMPPort">
                <span class="help-block">{{errors.first('base.RTMPPort')}}</span>
            </div>
        </div>
        <div :class="['form-group' , {'has-error': errors.has('base.RecordPath')}]" v-if="serverInfo.VersionType != '标准版'">
            <label for="base-record-path" class="col-sm-3 control-label">录像存储目录</label>
            <div class="col-sm-8">
                <input id="base-record-path" type="text" class="form-control" name="RecordPath" data-vv-as="录像存储目录" v-model.trim="RecordPath">
                <span class="help-block">{{errors.first('base.RecordPath')}}</span>
            </div>
        </div>
        <div :class="['form-group' , {'has-error': errors.has('base.ChannelSnapInterval')}]">
            <label for="base-channel-snap-interval" class="col-sm-3 control-label">快照间隔(分)</label>
            <div class="col-sm-8">
                <input id="base-channel-snap-interval" type="text" class="form-control" name="ChannelSnapInterval" data-vv-as="快照间隔" v-validate="'required|integer'" v-model.trim.number="ChannelSnapInterval">
                <span class="help-block">{{errors.first('base.ChannelSnapInterval')}}</span>
            </div>
        </div>
        <div :class="{'form-group': true, 'has-error': errors.has('base.PreferStreamFmt')}" title="配置直播流优先使用的播放格式">
            <label for="base-prefer-stream-fmt" class="col-sm-3 control-label">首选直播格式</label>
            <div class="col-sm-8">
                <select id="base-prefer-stream-fmt" name="PreferStreamFmt" class="form-control" v-model.trim="PreferStreamFmt">
                    <option value="">自动选择</option>
                    <option value="WEBRTC">WEBRTC</option>
                    <option value="FLV">FLV</option>
                    <option value="WS_FLV">WS_FLV</option>
                    <option value="HLS">HLS</option>
                    <option value="RTMP">RTMP</option>
                    <option value="RTSP">RTSP</option>
                </select>
                <span class="help-block">{{errors.first('base.PreferStreamFmt')}}</span>
            </div>
        </div>
        <div :class="['form-group' , {'has-error': errors.has('base.RTSPPort')}]" title="配置为0, 表示不开启RTSP分发">
            <label for="base-rtsp-port" class="col-sm-3 control-label">RTSP 端口(可选)</label>
            <div class="col-sm-8">
                <input id="base-rtsp-port" type="text" class="form-control" name="RTSPPort" data-vv-as="RTSP 端口" v-validate="'numeric'" v-model.trim.number="RTSPPort" placeholder="默认不开启RTSP分发">
                <span class="help-block">{{errors.first('base.RTSPPort')}}</span>
            </div>
        </div>
        <div :class="{'form-group': true, 'has-error': errors.has('base.HTTPSPort')}" title="配置为0, 表示不开启HTTPS">
            <label for="base-https-port" class="col-sm-3 control-label">HTTPS 端口(可选)</label>
            <div class="col-sm-8">
                <input id="base-https-port" type="text" class="form-control" name="HTTPSPort" data-vv-as="HTTPS 端口" v-validate="'numeric'" v-model.trim.number="HTTPSPort" placeholder="默认不开启HTTPS">
                <span class="help-block">{{errors.first('base.HTTPSPort')}}</span>
            </div>
        </div>
        <div :class="{'form-group': true, 'has-error': errors.has('base.HTTPSCertFile')}" title="配置 Cert 证书路径，绝对路径" v-if="HTTPSPort">
            <label for="base-https-cert-file" class="col-sm-3 control-label">HTTPS Cert 证书路径</label>
            <div class="col-sm-8">
                <div class="input-group">
                    <input id="base-https-cert-file" type="text" class="form-control" spellcheck="false" autocomplete="off" name="HTTPSCertFile" v-model.trim="HTTPSCertFile" placeholder="配置cert证书绝对路径">
                    <el-upload action="/api/v1/ssl/cert/import" accept=".pem,.cer,.crt,.csr,.der" :show-file-list="false" class="input-group-btn"
                        :on-success="onUploadCertSuccess" :on-error="onUploadCertError" :on-progress="onUploadCertProgress">
                        <button type="button" class="btn btn-default" style="border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:0;border-left:0;" title="上传Cert证书">
                            <i class="fa fa-upload"></i>
                        </button>
                    </el-upload>
                </div>
                <span class="help-block">{{errors.first('base.HTTPSCertFile')}}</span>
            </div>
        </div>
        <div :class="{'form-group': true, 'has-error': errors.has('base.HTTPSKeyFile')}" title="配置 Key 证书路径，绝对路径" v-if="HTTPSPort">
            <label for="base-https-key-file" class="col-sm-3 control-label">HTTPS Key 证书路径</label>
            <div class="col-sm-8">
                <div class="input-group">
                    <input id="base-https-key-file" type="text" class="form-control" spellcheck="false" autocomplete="off" name="HTTPSKeyFile" v-model.trim="HTTPSKeyFile" placeholder="配置key证书绝对路径">
                    <el-upload action="/api/v1/ssl/key/import" accept=".pem,.cer,.crt,.csr,.der,.key" :show-file-list="false" class="input-group-btn"
                        :on-success="onUploadKeySuccess" :on-error="onUploadKeyError" :on-progress="onUploadKeyProgress">
                        <button type="button" class="btn btn-default" style="border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:0;border-bottom-left-radius:0;border-left:0;" title="上传Key证书">
                            <i class="fa fa-upload"></i>
                        </button>
                    </el-upload>
                </div>
                <span class="help-block">{{errors.first('base.HTTPSKeyFile')}}</span>
            </div>
        </div>
        <div class="form-group">
            <label for="service-check-auth" class="col-sm-3 control-label">其它配置</label>
            <div class="col-sm-8 checkbox">
                <el-checkbox title="开启后接口调用需校验权限" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="APIAuth" name="APIAuth">
                    接口鉴权&nbsp;&nbsp;
                </el-checkbox>
                <el-checkbox title="不禁用时允许游客访问部分页面" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="LiveStreamAuth" name="LiveStreamAuth">
                    禁止游客访问&nbsp;&nbsp;
                </el-checkbox>
                <el-checkbox title="加快启播速度，相应也会增大一点延时" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="GOPCache" name="GOPCache">
                    直播秒开&nbsp;&nbsp;
                </el-checkbox>
                <el-checkbox title="直接输出H265_FLV，不做转码，防止服务器性能过载" style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="OutHevc" name="OutHevc">
                    H265_FLV
                </el-checkbox>
                <p class="text-danger" v-show="remoteAPIAuth === false && !APIAuth">
                    <br>
                    <i class="fa fa-exclamation-circle"></i> 接口鉴权关闭状态, 表示不需要登录即可访问系统, 可能导致不可预测的安全风险!
                    <br>
                </p>
                <p class="text-danger" v-show="remoteAPIAuth && !APIAuth">
                    <br>
                    <i class="fa fa-exclamation-circle"></i> 关闭接口鉴权, 表示不需要登录即可访问系统, 可能导致不可预测的安全风险, 谨慎操作!
                    <br>
                </p>
                <el-checkbox style="margin-left:-19px;margin-top:-5px;" size="small" v-model.trim="confirmAPIAuth" name="confirmAPIAuth" v-show="remoteAPIAuth && !APIAuth">
                    <span class="text-danger">我已知悉关闭接口鉴权带来的安全风险</span>
                </el-checkbox>
                <span class="help-block"></span>
            </div>
        </div>
        <br>
        <div class="form-group">
            <div class="col-sm-offset-3 col-sm-8">
                <button type="submit" class="btn btn-primary" ref="subBase" :disabled="isBasicNoChange || errors.any('base') || (remoteAPIAuth && !APIAuth && !confirmAPIAuth) || bCommitting || bUploading">{{bCommitting ? "提交中...":"保存"}}</button>
            </div>
        </div>
    </form>
</div>
</template>

<script>
import $ from "jquery";
import { mapState } from "vuex";

export default {
    data() {
        return {
            bCommitting: false,
            bRedirecting: false,
            bUploading: false,
            ServiceWanPort: 0,
            RTMPPort: 0,
            RTSPPort: "",
            GOPCache: false,
            ChannelSnapInterval: "",
            LiveStreamAuth: false,
            PreferStreamFmt: "",
            APIAuth: false,
            remoteAPIAuth: undefined,
            confirmAPIAuth: false,
            remoteBasicData: "",
            RecordPath: "",
            HTTPSPort: "",
            HTTPSCertFile: "",
            HTTPSKeyFile: "",
            preHTTPSPort: "",
            preHTTPPort: "",
            OutHevc: false,
        }
    },
    mounted() {
        this.getBaseConfig();
    },
    watch: {
        APIAuth: function(val, oldVal) {
            if(!val) {
                this.confirmAPIAuth = false;
            }
        },
    },
    methods: {
        async onSubmit() {
            var ok = await this.$validator.validateAll('base');
            if (!ok) {
                var e = this.errors.items[0];
                this.$message({
                    type: "error",
                    message: e.msg
                });
                $(`[name=${e.field}]`).focus();
                return;
            }
            var commitObject = this.getBasicCommitObject();
            if(this.remoteAPIAuth && !commitObject.APIAuth && !this.confirmAPIAuth) {
                this.$message({
                    type: "error",
                    message: "关闭接口鉴权, 需要确认知悉安全风险"
                });
                return;
            }
            var currentHttpPort = commitObject.ServiceWanPort;
            var currentHttpsPort = commitObject.HTTPSPort;

            this.bCommitting = true;
            $.get("/api/v1/setbaseconfig", commitObject).then(data => {
                if ((data.LiveQing || data.NVR).Header.ErrorNum == 200) {
                    if ((location.protocol == "http:" && this.preHTTPPort != currentHttpPort) ||
                        (location.protocol == "https:" && this.preHTTPSPort != currentHttpsPort)) {
                        var p = location.protocol;
                        var hostPort = currentHttpPort == 80 ? "" : ":" + currentHttpPort;
                        if (p == "https:") {
                            if (currentHttpsPort != 0) {
                                hostPort = currentHttpsPort == 443 ? "" : ":" + currentHttpsPort;
                            } else {
                                p = "http:";
                            }
                        }
                        this.bRedirecting = true;
                        this.runTestRedirect(`${p}//${location.hostname}${hostPort}/api/v1/getbaseconfig`, `${p}//${location.hostname}${hostPort}/#/config/base`);
                    } else {
                        if ((location.protocol == "http:" && this.preHTTPPort == currentHttpPort) || (location.protocol == "https:" && this.preHTTPSPort == currentHttpsPort)) {
                            this.runTest();
                        } else {
                            this.$message({
                                type: "success",
                                message: "配置成功！"
                            });
                            this.bCommitting = false;
                        }
                    }
                } else {
                    this.$message({
                        type: "error",
                        message: "配置失败！"
                    });
                    this.bCommitting = false;
                }
            }).fail(() => {
                this.bCommitting = false;
            })
        },
        getBasicCommitObject() {
            return {
                ServiceWanPort: this.ServiceWanPort,
                RTMPPort: this.RTMPPort,
                RTSPPort: this.RTSPPort,
                GOPCache: this.GOPCache,
                ChannelSnapInterval: this.ChannelSnapInterval,
                LiveStreamAuth: this.LiveStreamAuth,
                PreferStreamFmt: this.PreferStreamFmt,
                RecordPath: this.RecordPath,
                APIAuth: this.APIAuth,
                HTTPSPort: this.HTTPSPort,
                HTTPSCertFile: this.HTTPSCertFile,
                HTTPSKeyFile: this.HTTPSKeyFile,
                OutHevc: this.OutHevc,
            };
        },
        getBaseConfig() {
            $.get("/api/v1/getbaseconfig").then(ret => {
                var body = (ret.LiveQing || ret.NVR).Body;
                this.ServiceWanPort = body.ServiceWanPort || "";
                this.RTMPPort = body.RTMPPort || "";
                this.RTSPPort = body.RTSPPort || "";
                this.GOPCache = body.GOPCache;
                this.ChannelSnapInterval = body.ChannelSnapInterval;
                this.LiveStreamAuth = body.LiveStreamAuth;
                this.PreferStreamFmt = body.PreferStreamFmt;
                this.RecordPath = body.RecordPath;
                this.APIAuth = body.APIAuth;
                this.remoteAPIAuth = body.APIAuth;
                this.HTTPSPort = body.HTTPSPort || "";
                this.HTTPSCertFile = body.HTTPSCertFile;
                this.HTTPSKeyFile = body.HTTPSKeyFile;
                this.preHTTPPort = body.ServiceWanPort || "";
                this.preHTTPSPort = body.HTTPSPort || "";
                this.OutHevc = body.OutHevc || false;
                this.remoteBasicData = JSON.stringify(this.getBasicCommitObject());
            });
        },
        runTest() {
            setTimeout(() => {
                $.ajax({
                    method: "GET",
                    url: "/api/v1/getbaseconfig",
                    global: false,
                }).then(() => {
                    this.$message({
                        type: "success",
                        message: "配置成功！"
                    });
                    this.bCommitting = false;
                    this.getBaseConfig();
                }).fail(xhr => {
                    if(xhr && xhr.status == 401) {
                        this.bCommitting = false;
                        this.getBaseConfig();
                        return
                    }
                    this.runTest();
                })
            }, 1000);
        },
        runTestRedirect(t, r) {
            setTimeout(() => {
                $.ajax({
                    method: "GET",
                    url: t,
                    global: false,
                }).then(() => {
                    this.bRedirecting = false;
                    window.location.href = r;
                }).fail(xhr => {
                    if(xhr && xhr.status == 401) {
                        this.bRedirecting = false;
                        window.location.href = r;
                        return
                    }
                    this.runTestRedirect(t, r);
                })
            }, 1000);
        },
        onUploadCertSuccess(res, file, fileList) {
            this.bUploading = false;
            this.HTTPSCertFile = res;
            this.$message({
                type: "success",
                message: "上传Cert证书成功！"
            });
        },
        onUploadCertProgress(evt, file, fileList) {
            this.bUploading = true;
        },
        onUploadCertError(err, file, fileList) {
            this.bUploading = false;
            if (err) {
                this.$message({
                    type: "error",
                    message: err + ""
                })
            }
        },
        onUploadKeySuccess(res, file, fileList) {
            this.bUploading = false;
            this.HTTPSKeyFile = res;
            this.$message({
                type: "success",
                message: "上传Key证书成功！"
            });
        },
        onUploadKeyProgress(evt, file, fileList) {
            this.bUploading = true;
        },
        onUploadKeyError(err, file, fileList) {
            this.bUploading = false;
            if (err) {
                this.$message({
                    type: "error",
                    message: err + ""
                })
            }
        },
    }, //-- methods
    computed: {
        ...mapState([ "serverInfo" ]),
        isBasicNoChange() {
            var localeData = JSON.stringify(this.getBasicCommitObject());
            return this.remoteBasicData.localeCompare(localeData) == 0;
        }
    }
}
</script>
